package services

import (
	"fmt"
	"go-tool/components"
	"go-tool/db"
	"go-tool/db/orm_iray_proxy"
	"os"
	"path/filepath"
	"strings"
	"time"
)

type JobIrayObj struct {
	Timestamp      time.Time `json:"@timestamp"`
	RenderedTime   string    `json:"renderedTime"`
	JobID          string    `json:"jobId"`
	FinishedTime   string    `json:"finishedTime"`
	TotalCost      int64     `json:"totalCost"`
	StartTime      string    `json:"startTime"`
	Ts             time.Time `json:"ts"`
	Height         int       `json:"height"`
	LogTopic       string    `json:"log_topic"`
	RenderCost     int64     `json:"renderCost"`
	WaitRenderCost int64     `json:"waitRenderCost"`
	UploadCost     int       `json:"uploadCost"`
	Msg            string    `json:"msg"`
	Stat           string    `json:"stat"`
	Priority       int       `json:"priority"`
	HostIP         string    `json:"host_ip"`
	Width          int       `json:"width"`
	MaxIterations  int       `json:"maxIterations"`
	SubmitTime     string    `json:"submitTime"`
	Level          string    `json:"level"`
	Success        bool      `json:"success"`
}

func (e *JobIrayObj) DbJobInfoToJobObj(info orm_iray_proxy.JobInfo) *JobIrayObj {
	e = &JobIrayObj{
		Timestamp:      info.FinishedTime.Time.UTC(),
		RenderedTime:   info.FinishedTime.Time.Local().Format("2006-01-02 15:04:05"),
		JobID:          info.JobId,
		FinishedTime:   info.FinishedTime.Time.Local().Format("2006-01-02 15:04:05"),
		TotalCost:      info.FinishedTime.Time.Local().Unix() - info.SubmitTime.Time.Unix(),
		StartTime:      time.Unix(info.FinishedTime.Time.Unix()-int64(info.RenderTime.Float64), 0).Local().Format("2006-01-02 15:04:05"), //减去渲染时长 rendercost
		Ts:             info.FinishedTime.Time.Local(),
		Height:         info.Height,
		LogTopic:       "cloud-rendering-stat",
		RenderCost:     int64(info.RenderTime.Float64),
		WaitRenderCost: info.FinishedTime.Time.Local().Unix() - info.SubmitTime.Time.Unix() - int64(info.RenderTime.Float64),
		UploadCost:     0,
		Msg:            "irayJobStat",
		Stat:           "irayJobStat",
		Priority:       info.Priority,
		HostIP:         info.Ip.String,
		Width:          info.Width,
		MaxIterations:  info.MaxIterations,
		SubmitTime:     info.SubmitTime.Time.Local().Format("2006-01-02 15:04:05"),
		Level:          "info",
		Success:        true,
	}
	return e
}

func (e *JobIrayObj) ErgodicFiles() {
	path := "/data/iray_db_back"
	err := filepath.Walk(path, func(path string, f os.FileInfo, err error) error {
		if f == nil {
			return err
		}
		if f.IsDir() {
			return nil
		}
		fmt.Println("path: ", path)
		if strings.Index(path, ".db") > 0 {
			count := e.EachJobs(e.GetJobs(path))
			fmt.Println("count: ", count)
		} else {
			fmt.Println("err path:", path)
		}
		return nil
	})
	if err != nil {
		fmt.Printf("filepath.Walk() returned %v\n", err)
	}
}

func (e *JobIrayObj) GetJobs(path string) (jobs []orm_iray_proxy.JobInfo) {
	ip := path[strings.Index(path, "r_")+2 : strings.Index(path, ".db")]
	fmt.Println(ip)
	db.InitDbLite(path)
	sqlStr := `SELECT Name job_id, DateCreated start_time, DateCreated submit_time, DateModified finished_time,
				Height as height, Width as width, Priority as priority,MaxIterations max_iterations, b.RenderTime render_time
				from jobs 
				LEFT JOIN job_snapshots b on b.JobID=jobs.UUID
				where b.RenderTime>0 and finished_time>="2019-07-31 16"`
	err := db.DbLite.Select(&jobs, sqlStr)
	if err != nil {
		fmt.Printf("query failed, err:%v\n", err)
		return
	}
	for i := 0; i < len(jobs); i++ {
		jobs[i].Ip.String = ip
		jobs[i].Ip.Valid = true
	}
	return
}

func (e *JobIrayObj) InsertEs() (err error) {
	components.EsClient.Index = "cloud-rendering-stat-" + e.Timestamp.Local().Format("2006.01")
	components.EsClient.Type = "doc"
	put, err := components.EsClient.Push(e)
	if err != nil {
		fmt.Printf("Indexed %s to index %s, type %s\n, job_id %s", put.Id, put.Index, put.Type, e.JobID)
		panic(err)
	}
	return
}

func (e *JobIrayObj) EachJobs(jobs []orm_iray_proxy.JobInfo) (count int) {
	for i := 0; i < len(jobs); i++ {
		e.DbJobInfoToJobObj(jobs[i]).InsertEs()
		count++
	}
	return
}
